/*******************************************************************************
 *	                           FPM383 driver
 *******************************************************************************/
#include "FPM383_driver.h"
#include "str_ext.h"
#include "dataproc.h"

/*******************************************************************************
 * @brief  配置值
 *******************************************************************************/
const uu08 FPM383_head_dat[8] = {0xF1, 0x1F, 0xE2, 0x2E, 0xB6, 0x6B, 0xA8, 0x8A};

#define FPM383_HEAD_LEN 11
#define FPM383_CMD_BASE_LEN 7
#define FPM383_RSP_BASE_LEN 11

/*******************************************************************************
 * @brief: 命令发送
 * @param obj
 * @param cmd
 * @return {*}
 ******************************************************************************/
int FPM383_cmd_send(FPM383_def_type *obj, FPM383_cmd_req_type *cmd)
{
	int len, cnt;
	uu16 app_len;
	uu08 *buff = obj->buff;

	// 帧头
	copy_u8(FPM383_head_dat, buff, 8);

	// 应用长度
	app_len = cmd->dat_len + FPM383_CMD_BASE_LEN;
	buff[8] = app_len >> 8;
	buff[9] = app_len & 0xFF;

	// 帧头校验校验码
	buff[10] = lrc_u8(buff, len);

	// 应用密码
	len = 11;
	buff[len++] = cmd->password.byte.MB.uval;
	buff[len++] = cmd->password.byte.UB.uval;
	buff[len++] = cmd->password.byte.HB.uval;
	buff[len++] = cmd->password.byte.LB.uval;

	// 命令码
	buff[len++] = cmd->cmd.byte.HB.uval;
	buff[len++] = cmd->cmd.byte.LB.uval;

	// 数据
	for (cnt = 0; cnt < cmd->dat_len; cnt++)
		buff[len++] = cmd->dat[cnt];

	// 校验和
	buff[len++] = lrc_u8(&buff[FPM383_HEAD_LEN], len - FPM383_HEAD_LEN);

	// 发送
	obj->dat_send(buff, len);

	return 0;
}

/*******************************************************************************
 * @brief: 命令应答
 * @param obj
 * @param cmd
 * @return {*}
 ******************************************************************************/
int FPM383_cmd_rsp(FPM383_def_type *obj, FPM383_cmd_rsp_type *rsp, uu16 dat_len_max)
{
	ii16 len, app_len, index, cnt;
	int err = 0;
	uu08 *buff;

	buff = obj->buff;

	len = obj->dat_read(buff, obj->buff_size);

	if (len < FPM383_HEAD_LEN + FPM383_RSP_BASE_LEN)
		return (err = FPM383_ERR_RSP_LEN);

	if (lrc_u8(buff, FPM383_HEAD_LEN) != 0)
		return (err = FPM383_ERR_RSP_HEAD_LRC);

	app_len = (buff[8] << 8) + buff[9];
	if (len != app_len + FPM383_HEAD_LEN)
		return (err = FPM383_ERR_RSP_LEN);

	if (lrc_u8(&buff[FPM383_HEAD_LEN], app_len) != 0)
		return (err = FPM383_ERR_RSP_DATA_LRC);

	// 读密码
	index = FPM383_HEAD_LEN;
	rsp->password.byte.MB.uval = buff[index++];
	rsp->password.byte.UB.uval = buff[index++];
	rsp->password.byte.HB.uval = buff[index++];
	rsp->password.byte.LB.uval = buff[index++];

	// 命令
	rsp->cmd.byte.HB.uval = buff[index++];
	rsp->cmd.byte.LB.uval = buff[index++];

	// 错误码
	rsp->err_code.byte.MB.uval = buff[index++];
	rsp->err_code.byte.UB.uval = buff[index++];
	rsp->err_code.byte.HB.uval = buff[index++];
	rsp->err_code.byte.LB.uval = buff[index++];

	// 数据
	for (cnt = 0; cnt < dat_len_max && index < len - 1; cnt++)
	{
		rsp->dat[cnt] = buff[index++];
	}
	rsp->dat_len = cnt;

	return FPM383_ERR_OK;
}

/*******************************************************************************
 * @brief: 命令应答
 * @param obj
 * @param cmd
 * @return {*}
 ******************************************************************************/

/*******************************************************************************
 * @brief: 注册
 * @param obj
 * @param cmd
 * @return {*}
 ******************************************************************************/
int FPM383_reg(FPM383_def_type *obj, FPM383_cmd_req_type *cmd)
{
}

/*******************************************************************************
 * @brief: 查询注册结果
 * @param obj
 * @param reg_st 状态
 * @return 错误码
 ******************************************************************************/
int FPM383_reg_query(FPM383_def_type *obj, FPM383_reg_st_type *reg_st)
{
	FPM383_cmd_req_type cmd;
	FPM383_cmd_rsp_type rsp;
	uu08 buff[4];
	int err = 0, err_cnt = 0;

	cmd.password.uval = 0;
	cmd.dat_len = 0;
	cmd.cmd.uval = 0x0112;
	cmd.dat = buff;

	while (err_cnt < 3)
	{
		FPM383_cmd_send(obj, &cmd);

		rsp.dat = buff;
		err = FPM383_cmd_rsp(obj, &rsp, 3);

		if (err == 0 && rsp.err_code.uval == 0)
		{
			reg_st->id.byte.HB.uval = buff[0];
			reg_st->id.byte.LB.uval = buff[1];
			reg_st->proc = buff[2];

			break;
		}
		else
		{
			err_cnt++;
		}
	}

	return err;
}

/*******************************************************************************
 * @brief: 查询保存结果
 * @param obj
 * @param id
 * @return 错误码
 ******************************************************************************/
int FPM383_save_query(FPM383_def_type *obj, ii16 *id)
{
	FPM383_cmd_req_type cmd;
	FPM383_cmd_rsp_type rsp;
	uu08 buff[4];
	int err = 0, err_cnt = 0;

	cmd.password.uval = 0;
	cmd.dat_len = 0;
	cmd.cmd.uval = 0x0114;
	cmd.dat = buff;

	while (err_cnt < 3)
	{
		FPM383_cmd_send(obj, &cmd);

		rsp.dat = buff;
		err = FPM383_cmd_rsp(obj, &rsp, 2);

		if (err == 0 && rsp.err_code.uval == 0)
		{
			*id = (buff[0] << 8) + buff[1];
			break;
		}
		else
		{
			*id = -1;
			err_cnt++;
		}
	}

	return err;
}
